package com.yizhuoyan.his.serviceimpl.admin;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yizhuoyan.his.ao.ModifyUserAo;
import com.yizhuoyan.his.ao.UserAddAo;
import com.yizhuoyan.his.dao.SysAccountDao;
import com.yizhuoyan.his.dao.SysRoleDao;
import com.yizhuoyan.his.dto.QueryResult;
import com.yizhuoyan.his.entity.SysAccountEntity;
import com.yizhuoyan.his.exception.HISDataExistsException;
import com.yizhuoyan.his.service.admin.SysAccountManageService;
import com.yizhuoyan.his.servicesupport.DatabaseIdGenerateSupportService;
import com.yizhuoyan.his.util.BeanMap;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 用户管理
 */
@Transactional
@Validated
@Service
@Slf4j
public class SysAccountManageServiceImpl implements SysAccountManageService {
    @Autowired
    SysAccountDao sysAccountDao;
    @Autowired
    SysRoleDao sysRoleDao;
    @Autowired
    DatabaseIdGenerateSupportService databaseIdGenerateSupportService;

    @Override
    public SysAccountEntity addUser(@NonNull UserAddAo ao) throws Exception {
        // 1验证参数


        log.trace("添加用户基本信息,参数为：{}", ao);
        String account = ao.getAccount();
        String password = ao.getPassword();
        String nickname = ao.getNickname();
        Long roleId = ao.getRoleId();
        //1.1账号不能重复
        if (sysAccountDao.exists("account", account)) {
            log.trace("用户账号{}已存在，不可以添加", account);
            throw new HISDataExistsException(String.format("账号[%s]已存在", account));
        }
        log.trace("用户账号{}不存在，可以添加", account);
        // 2业务逻辑
        SysAccountEntity e = new SysAccountEntity();
        //雪花算法生成id
        Long id = databaseIdGenerateSupportService.nextId();
        e.setId(id);
        e.setAccount(account);
        e.setPassword(password);
        e.setNickname(nickname);
        e.setRoleId(roleId);
        e.setCreateTime(LocalDateTime.now());
        e.setLastUpdatePasswordTime(null);
        e.setLastLoginTime(null);
        sysAccountDao.insert(e);
        log.trace("添加用户基本信息成功,参数为：{}", ao);
        return e;
    }

    @Override
    public void modifyUser(@NonNull Long id, ModifyUserAo ao) throws Exception {
        // 1验证参数
        if (!sysAccountDao.exists("id", id)) {
            log.trace("用户{}不存在，不可以修改", id);
            throw new HISDataExistsException(String.format("用户[%s]不存在", id));
        }
        SysAccountEntity e = sysAccountDao.selectById(id);
        // 2业务逻辑
        BeanMap updateMap = BeanMap.of(6);
        String newAccount = ao.getAccount();
        //2.1修改账号
        log.trace("判断Account是否需要修改");
        if (!Objects.equals(newAccount, e.getAccount())) {
            log.trace("Account需要修改,判断新Account是否已存在");
            if (sysAccountDao.exists("account", newAccount)) {
                log.trace("用户账号{}已存在，不可以添加", newAccount);
                throw new HISDataExistsException(String.format("用户账号[%s]已存在", newAccount));
            }
            log.trace("newCode合法，可以修改");
            updateMap.append("code", newAccount);
        }
        //2.2修改名称
        log.trace("判断nickname是否需要修改");
        String newNickname = ao.getNickname();
        if (!Objects.equals(newNickname, e.getNickname())) {
            log.trace("newNickname合法，可以修改");
            updateMap.append("nickname", newNickname);
        }
        //2.3修改密码,若修改成功，修改最后修改密码时间
        log.trace("判断password是否需要修改");
        String newPassword=ao.getPassword();
        if(!Objects.equals(newPassword,e.getPassword())){
            updateMap.append("password",newPassword);
            updateMap.append("lastUpdatePasswordTime",LocalDateTime.now());
        }
        //2.4修改角色id
        log.trace("判断roleId是否需要修改");
        Long newRoleId=e.getRoleId();
        if(!Objects.equals(newRoleId,e.getRoleId())){
            log.trace("判断roleId是否存在");
            if(sysRoleDao.exists("id",newRoleId)){
                updateMap.append("roleId",newRoleId);
            }else{
                throw new Exception(String.format("角色[%s]不存在", newRoleId));
            }
        }
        // 修改
        if(!updateMap.isEmpty()){
            log.trace("执行更新，需要修改字段为{}",updateMap);
            sysAccountDao.update(id,updateMap);
        }
    }

    @Override
    public void removeUser(@NonNull Long id) throws Exception {
        // 1验证参数
        //id不存在或已删除
        if (!sysAccountDao.exists("id", id)) {
            log.trace("用户{}不存在，不可以删除", id);
            throw new HISDataExistsException(String.format("用户[%s]不存在", id));
        }
        // 2业务逻辑
        //2.1 deleted=0时
        if (sysAccountDao.selectById(id).getDeleted() == 0) {
            sysAccountDao.update(id, BeanMap.ofOnly("deleted", 1l));
        } else {
            //2.2deleted=1l时
            sysAccountDao.delete(id);
            log.trace("彻底删除");
        }
    }

    @Override
    public SysAccountEntity queryUser(@NonNull Long id) throws Exception {
        // 1验证参数
        if(!sysAccountDao.exists("id",id)){
            throw new  Exception("查询id不存在");
        }
        // 2业务逻辑
        SysAccountEntity e = sysAccountDao.selectById(id);
        return e;
    }

    @Override
    public QueryResult<SysAccountEntity> queryUserByKey(String key, int pageNo, int pageSize) throws Exception {
        // 1验证参数
        if (key != null) {
            if ((key = key.trim()).length() == 0)
                key = null;
            else
                key = key.trim();
        }
        if (pageNo <= 0) {
            pageNo = 1;
        }
        if (pageSize <= 0) {
            pageSize = 5;
        }
        // 2业务逻辑
        PageHelper.startPage(pageNo, pageSize);
        PageInfo<SysAccountEntity> page = new PageInfo<>(sysAccountDao.selectByKeyWithPagination(key, pageNo, pageSize));
        // 3 组装结果
        QueryResult<SysAccountEntity> result = new QueryResult<SysAccountEntity>();
        result.setPageNo(pageNo);
        result.setRows(page.getList());
        result.setTotalRows(page.getTotal());
        result.setPageSize(pageSize);
        return result;
    }
}
